home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Play sound buffer
-
- */
-
- #include "netfone.h"
-
- /* GSMDECOMP -- Uncompress the contents of a sound buffer using GSM. */
-
- static void gsmdecomp(sb)
- struct soundbuf *sb;
- {
- gsm_signal dst[160];
- int i, j, l = 0;
- char *dpx = ((char *) sb->buffer.buffer_val) + sizeof(short);
- static char dcb[BUFL];
- short declen = *((short *) sb->buffer.buffer_val);
-
- revshort(&declen);
- if (declen <= 0 || declen > 1600) {
- declen = 1600;
- }
- for (i = 0; i < sb->buffer.buffer_len - sizeof(short);
- i += sizeof(gsm_frame)) {
- gsm_decode(gsmh, (gsm_byte *) dpx, dst);
- dpx += sizeof(gsm_frame);
- for (j = 0; j < 160; j++) {
- dcb[l++] = audio_s2u(dst[j]);
- }
- }
- _fmemcpy(sb->buffer.buffer_val, dcb, declen);
- sb->buffer.buffer_len = declen;
- }
-
- /* ADPCMDECOMP -- Decompress the contents of a sound buffer using ADPCM. */
-
- void adpcmdecomp( struct soundbuf *sb)
- {
- #define TINY_PACKETS 512
- char *dp = (char *) sb->buffer.buffer_val;
- unsigned char *sp;
- static unsigned char dob[TINY_PACKETS * 2];
- struct adpcm_state adpcm;
-
- /* Restore the decoder state from the copy saved in the packet,
- independent of the byte order of the machine we're running on. */
-
- sp = (unsigned char *) dp + (sb->buffer.buffer_len - 3);
- adpcm.valprev = (short) ((((int) sp[0]) << 8) | ((int) sp[1]));
- adpcm.index = sp[2];
- sb->buffer.buffer_len -= 3;
-
- adpcm_decoder_u(dp, dob, (int) (sb->buffer.buffer_len * 2), &adpcm);
- sb->buffer.buffer_len *= 2;
- _fmemcpy(dp, dob, (size_t) sb->buffer.buffer_len);
- }
-
- /* LPCDECOMP -- Uncompress the contents of a sound buffer using LPC. */
-
- static void lpcdecomp(struct soundbuf *sb)
- {
- int i, j, l = 0;
- char *dpx = ((char *) sb->buffer.buffer_val) + sizeof(short);
- static char dcb[1800];
- short declen = *((short *) sb->buffer.buffer_val);
-
- if (declen <= 0 || declen > 1800) {
- declen = 1800;
- }
- for (i = 0; l < declen; i += sizeof(lpcparams_t)) {
- lpcparams_t *lp = (lpcparams_t *) (dpx + i);
-
- revshort(&(lp->period));
- j = lpc_synthesize(lp, 1.0, dcb + l);
- l += j;
- }
- _fmemcpy(sb->buffer.buffer_val, dcb, declen);
- sb->buffer.buffer_len = declen;
- }
-
- /* PLAYSOUND -- Play a sound buffer, decrypting and decompressing
- as required. */
-
- void playSound(HWND hWnd, LPCLIENT_DATA pClientData, soundbuf *d,
- int bitsPerSample, int samplesPerSecond)
- {
- LPWAVEHDR wh;
- short FAR *sbuf;
- unsigned char _huge *ulp;
- WORD stat;
- int i, len, dline;
- char *val;
- static unsigned char auxbuf[BUFL + 2];
- char bbuf[8], tbuf[8];
-
- /* If the message queue is close to exhaustion, ditch the output
- buffer to avoid a hangup due to queue overflow. */
-
- if (outputPending >= ((3 * messageQueueSize) / 4)) {
- propeller(IDC_PH_INPUT_LOST, ++inputPacketsLost);
- return;
- }
-
- if (pClientData != NULL) {
- pClientData->debugReq = (d->compression & fDebug) ? TRUE : FALSE;
- if (pClientData->debugReq && !IsIconic(hWnd)) {
- HDC hdc = GetDC(hWnd);
- char buf[80];
-
- wsprintf(buf, Format(44), d->buffer.buffer_len);
- lstrcat(buf,
- ((d->compression & (fComp2X | fCompGSM)) ==
- (fComp2X | fCompGSM)) ?
- rstring(IDS_T_GSM_2X) :
- ((d->compression & (fComp2X | fCompADPCM)) ==
- (fComp2X | fCompADPCM)) ?
- rstring(IDS_T_ADPCM_2X) :
- ((d->compression & (fComp2X | fCompLPC)) ==
- (fComp2X | fCompLPC)) ?
- rstring(IDS_T_LPC_2X) :
- ((d->compression & fComp2X) ? rstring(IDS_T_2X) :
- ((d->compression & fCompADPCM) ? rstring(IDS_T_ADPCM) :
- ((d->compression & fCompLPC) ? rstring(IDS_T_LPC) :
- ((d->compression & fCompGSM) ? rstring(IDS_T_GSM) : "")))));
- lstrcat(buf, rstring(IDS_SP_BYTES_PERIOD));
-
- TextOut(hdc, 1 * tmAveCharWidth, 5 * tmHeight, buf, strlen(buf));
- for (i = 6; i < 10; i++) {
- TextOut(hdc, 1 * tmAveCharWidth, i * tmHeight, blankit, strlen(blankit));
- }
- ReleaseDC(hWnd, hdc);
- }
- }
-
-
- wh = (LPWAVEHDR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
- sizeof(WAVEHDR));
- if (wh == NULL) {
- return;
- }
-
- /* Perform requested decryption and decompression of the
- received data. */
-
- len = (int) d->buffer.buffer_len;
- val = d->buffer.buffer_val;
-
- /* If the fSetDest bit is on, turn up the volume all the way
- if fDestJack is set. This indicates an attempt to get the
- user's attention, even in case he's turned the volume all
- the way down. */
-
- if (d->compression & fSetDest) {
- if (!(d->compression & fDestJack)) {
- waveOutSetVolume((UINT) hWaveOut, (DWORD) MAKELONG(0xFFFF, 0xFFFF));
- }
- }
-
- dline = 6;
-
- /* If message is encrypted, decrypt. */
-
- if ((d->compression & fEncOTP) && (pClientData->otpFileName[0])) {
- int i;
-
- if (pClientData->debugReq) {
- if (!IsIconic(hWnd)) {
- HDC hdc = GetDC(hWnd);
-
- WinPrintf(hdc, dline++, 1,
- rstring(IDS_T_KEY_FILE_STATUS), len);
- ReleaseDC(hWnd, hdc);
- }
- }
- for (i = 0; i < len; i ++) {
- val[i] ^= pClientData->otp[i];
- }
- }
- if ((d->compression & fEncPGP)) {
- unsigned short iv[4];
- int slen = (len + 7) & (~7);
- char twibble[16];
-
- /* Special gimmick: if we receive a PGP-encrypted packet while
- we're still waiting for PGP to complete decrypting the session
- key, ditch it. This is a lot easier on the user's ears when
- he's trying furiously to enter the private key phrase. */
-
- if (pClientData->pgpFileName[0] != 0) {
- propeller(IDC_PH_INPUT_LOST, ++inputPacketsLost);
- return;
- } else if (pClientData->pgpkey[0] != 0) {
- _fmemcpy(twibble, pClientData->pgpkey + 1, 16);
- _fmemset(iv, 0, sizeof(iv));
- initcfb_idea(iv, twibble, TRUE);
-
- if (pClientData->debugReq) {
- if (!IsIconic(hWnd)) {
- HDC hdc = GetDC(hWnd);
-
- WinPrintf( hdc, dline++, 1,
- rstring(IDS_T_PGP_STATUS), len);
- ReleaseDC(hWnd, hdc);
- }
- }
- ideacfb(val, slen);
- close_idea();
- }
- }
-
- if ((d->compression & fEncIDEA) && pClientData->ideaKeyString[0]) {
- unsigned short iv[4];
- int slen = (len + 7) & (~7);
- char twibble[16];
-
- _fmemcpy(twibble, pClientData->ideakey + 1, 16);
- _fmemset(iv, 0, sizeof(iv));
- initcfb_idea(iv, twibble, TRUE);
-
- if (pClientData->debugReq) {
- if (!IsIconic(hWnd)) {
- HDC hdc = GetDC(hWnd);
-
- WinPrintf( hdc, dline++, 1,
- rstring(IDS_T_IDEA_STATUS), len);
- ReleaseDC(hWnd, hdc);
- }
- }
- ideacfb(val, slen);
- close_idea();
- }
-
- if ((d->compression & fEncDES) && pClientData->desKeyString[0]) {
- int i;
- char twibble[8];
-
- _fmemcpy(twibble, pClientData->deskey + 1, 8);
- setkey(twibble);
-
- if (pClientData->debugReq) {
- if (!IsIconic(hWnd)) {
- HDC hdc = GetDC(hWnd);
-
- WinPrintf( hdc, dline++, 1,
- rstring(IDS_T_DES_STATUS), len);
- ReleaseDC(hWnd, hdc);
- }
- }
- for (i = 0; i < len; i += 8) {
- memcpy(tbuf, val + i, 8);
- dedes(val + i);
-
- /* Reverse cipher block chaining. */
-
- if (i > 0) {
- int j;
-
- for (j = 0; j < 8; j++) {
- val[(i + j)] ^= bbuf[j];
- }
- }
- memcpy(bbuf, tbuf, 8);
- }
- }
-
- /* If message is compressed, decompress appropriately. */
-
- if (d->compression & fCompGSM) {
- gsmdecomp(d);
- len = (int) d->buffer.buffer_len;
- }
-
- if (d->compression & fCompADPCM) {
- adpcmdecomp(d);
- len = (int) d->buffer.buffer_len;
- }
-
- if (d->compression & fCompLPC) {
- lpcdecomp(d);
- len = (int) d->buffer.buffer_len;
- }
-
- if (d->compression & fComp2X) {
- int i;
- register char *ab = auxbuf;
-
- for (i = 0; i < len; i++) {
- *ab++ = i == 0 ? *val :
- (audio_s2u((audio_u2s(*val) + audio_u2s(val[-1])) / 2));
- *ab++ = *val++;
- }
- len *= 2;
- val = auxbuf;
- }
-
- if (samplesPerSecond == 11025) {
- if (bitsPerSample == 16) {
-
- /* Convert the resulting u-law samples in the sound buffer
- to 16 bit signed linear format. */
-
- wh->lpData = (LPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
- (DWORD) (((BUFL * ((DWORD) sizeof(short)) * 12) / 8)));
- if (wh->lpData == NULL) {
- GlobalFreePtr(wh);
- return;
- }
- sbuf = (short FAR *) wh->lpData;
- ulp = (unsigned char *) val;
-
- for (i = 0; i < len; i++) {
- int j = i & 7;
- *sbuf++ = audio_u2s(*ulp);
- // This should be written out for better optimisation
- if (j > 0 && !(j & 1)) {
- *sbuf++ = audio_u2s(*ulp);
- } else if (j % 320 == 319) {
- *sbuf++ = audio_u2s(*ulp);
- }
- ulp++;
- }
- wh->dwBufferLength = wh->dwBytesRecorded =
- (((LPSTR) sbuf) - wh->lpData);
- } else if (bitsPerSample == 8) {
- BYTE FAR *bbuf;
-
- /* Convert the resulting u-law samples in the sound buffer
- to 8 bit PCM format. */
-
- wh->lpData = (LPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
- (DWORD) (((BUFL * ((DWORD) sizeof(short)) * 12) / 16)));
- if (wh->lpData == NULL) {
- GlobalFreePtr(wh);
- return;
- }
- bbuf = (BYTE FAR *) wh->lpData;
- ulp = (unsigned char *) val;
-
- for (i = 0; i < len; i++) {
- int j = i & 7;
- *bbuf++ = audio_u2c(*ulp);
- // This should be written out for better optimisation
- if (j > 0 && !(j & 1)) {
- *bbuf++ = audio_u2c(*ulp);
- } else if (j % 320 == 319) {
- *bbuf++ = audio_u2c(*ulp);
- }
- ulp++;
- }
- wh->dwBufferLength = wh->dwBytesRecorded =
- (((LPSTR) bbuf) - wh->lpData);
- }
- } else { // samplesPerSecond == 8000
- if (bitsPerSample == 16) {
-
- /* Convert the resulting u-law samples in the sound buffer
- to 16 bit signed linear format. */
-
- wh->lpData = (LPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
- (DWORD) (len * sizeof(short)));
- if (wh->lpData == NULL) {
- GlobalFreePtr(wh);
- return;
- }
- sbuf = (short FAR *) wh->lpData;
- ulp = (unsigned char *) val;
-
- for (i = 0; i < len; i++) {
- *sbuf++ = audio_u2s(*ulp++);
- }
- wh->dwBufferLength = wh->dwBytesRecorded =
- (((LPSTR) sbuf) - wh->lpData);
- } else if (bitsPerSample == 8) {
- BYTE FAR *bbuf;
-
- /* Convert the resulting u-law samples in the sound buffer
- to 8 bit PCM format. */
-
- wh->lpData = (LPSTR) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE,
- (DWORD) (len * sizeof(BYTE)));
- if (wh->lpData == NULL) {
- GlobalFreePtr(wh);
- return;
- }
- bbuf = (BYTE FAR *) wh->lpData;
- ulp = (unsigned char *) val;
-
- for (i = 0; i < len; i++) {
- *bbuf++ = audio_u2c(*ulp++);
- }
- wh->dwBufferLength = wh->dwBytesRecorded =
- (((LPSTR) bbuf) - wh->lpData);
- }
- }
-
- // Give the answering machine a chance to save the buffer
-
- if (!(d->compression & fPlayback)) {
- answerSave(pClientData->inetSock.sin_addr, pClientData->szHost, d);
- }
-
- wh->dwFlags = 0;
- waveOutPrepareHeader(hWaveOut, wh, sizeof(WAVEHDR));
- stat = waveOutWrite(hWaveOut, wh, sizeof(WAVEHDR));
- if (stat == 0) {
- outputPending++;
- if (hDlgPropeller != NULL) {
- char s[80];
-
- wsprintf(s, outputPending == 0 ? Format(6) : Format(7),
- outputPending);
- SetDlgItemText(hDlgPropeller, IDC_PH_AUDIO_OUT_QUEUE, s);
- }
- } else {
- char et[MAXERRORLENGTH];
-
- waveOutGetErrorText(stat, et, sizeof et);
- waveOutUnprepareHeader(hWaveOut, wh, sizeof(WAVEHDR));
- GlobalFreePtr(wh);
- MsgBox(hWnd, MB_OK | MB_ICONEXCLAMATION, Format(45), et);
- return;
- }
- }